package com.yn.iotxiao.controller.Open;

import com.alibaba.fastjson.JSONObject;
import com.yn.iotxiao.Utils.File.FileHelp;
import com.yn.iotxiao.Utils.HikHttpUtil;
import com.yn.iotxiao.Utils.JsonHelper;
import com.yn.iotxiao.Utils.StringUtil;
import com.yn.iotxiao.authorize.Authorize;
import com.yn.iotxiao.model.Hik.HikUser;
import com.yn.iotxiao.model.Hik.HikUserSetUp;
import com.yn.iotxiao.model.Hik.HikWeekPlanRequest;
import com.yn.iotxiao.model.Hik.HkDoorNoPlan;
import com.yn.iotxiao.response.ResponseResult;
import com.yn.iotxiao.sql.entity.Device.DeviceInfo;
import com.yn.iotxiao.sql.entity.Face.FaceInfo;
import com.yn.iotxiao.sql.entity.Group.GroupDevice;
import com.yn.iotxiao.sql.entity.Group.GroupInfo;
import com.yn.iotxiao.sql.services.Device.DeviceInfoService;
import com.yn.iotxiao.sql.services.Face.FaceInfoService;
import com.yn.iotxiao.sql.services.Group.GroupService;
import io.micrometer.common.util.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 *
 */
@RequestMapping("/v1/open")
@Slf4j
@RestController
@ResponseResult
public class OpenController {


    @Autowired
    GroupService gService;
    @Autowired
    DeviceInfoService dService;
    @Autowired
    FaceInfoService fService;


    /**
     * 创建人员信息
     *
     * @param user 人员信息
     * @return
     */
    @PostMapping("/basic/user/setup")
    public Object userSetUp(HttpServletRequest reqeust,@Validated HikUserSetUp user) throws Exception {

        //{"faceLibType":"blackFD","FDID":"1","FPID":"f054fff47a4b4b1787a92d2482571cd3"}
        //保存到人脸库
        //1、保存文件
        if (user.getFile() != null) {
            JSONObject fileinfo = FileHelp.saveWithFile(user.getFile(), reqeust.getServerName());
            FaceInfo faceInfo = new FaceInfo(user.getEmployeeNo(), user.getName(),
                    fileinfo.getString("url"),
                    fileinfo.getString("path"));
            int faceSave = fService.insert(faceInfo);
            if (faceSave < 0) {
                throw new Exception("人脸库保存失败");
            }
        } else {
            FaceInfo faceInfo = fService.getWithKey(user.getEmployeeNo());
            if (faceInfo == null || StringUtils.isBlank(faceInfo.getUid())) {
                faceInfo = new FaceInfo(user.getEmployeeNo(), user.getName(),
                        "",
                        "");
            } else {
                faceInfo.setName(user.getName());
            }
            int faceSave = fService.insert(faceInfo);
            if (faceSave < 0) {
                throw new Exception("人脸库保存失败");
            }
        }


        List<DeviceInfo> devices = new ArrayList<>();
        if (!user.getGroupId().equals("1")) {
            devices = gService.getDeviceInGroup(user.getGroupId(), "", 1, 100);
        } else {
            devices = dService.getList("", 1, 100);
        }

        //人员写入到权限组

        if (devices != null && devices.size() > 0) {
            for (DeviceInfo device :
                    devices) {
                if (device.getType() == 1) {
                    //海康门禁
                    //创建人员
                    HikHttpUtil httpUtil = new HikHttpUtil(device.getIp(), "/ISAPI/AccessControl/UserInfo/SetUp",
                            device.getLoginId(), device.getPassword());
                    //设置计划
                    HikUser hikUser = new HikUser(user.getEmployeeNo(), user.getName());
                    if (!user.getPlanNo().equals("1")) {
                        List<HkDoorNoPlan> plans = new ArrayList<>();
                        HkDoorNoPlan plan = new HkDoorNoPlan();
                        plan.setPlanTemplateNo(user.getPlanNo());
                        plans.add(plan);
                        hikUser.setRightPlan(plans);
                    }
                    JSONObject userBody = JsonHelper.create("UserInfo", hikUser);
                    try {
                        var userResponse = httpUtil.doBodyPut(userBody);
                        log.info("人员创建：" + userResponse.toString());
                    } catch (Exception e) {
                        log.info("人员创建失败：" + e.getLocalizedMessage());
                        throw new RuntimeException(e);
                    }
                    if (user.getFile() != null) {
                        //创建人脸
                        HikHttpUtil httpUtil2 = new HikHttpUtil(device.getIp(), "/ISAPI/Intelligent/FDLib/FDSetUp",
                                device.getLoginId(), device.getPassword());
                        JSONObject faceBody = JsonHelper.create("FaceDataRecord",
                                JsonHelper.create("faceLibType", "blackFD", "FDID", "1", "FPID", user.getEmployeeNo()));
                        try {
                            var faceResponse = httpUtil2.doFormDataPut(faceBody, user.getFile());
                            log.info("人脸创建：" + faceResponse.toString());
                        } catch (Exception e) {
                            log.info("人脸创建失败：" + e.getLocalizedMessage());
                            throw new RuntimeException(e);
                        }
                    }
                }else if(device.getType() == 2) {
                    //海康主机
                    //写入人脸库

                    HikHttpUtil httpUtil2 = new HikHttpUtil(device.getIp(), "/ISAPI/Intelligent/FDLib/pictureUpload?FDType=custom&type=concurrent",
                            device.getLoginId(), device.getPassword(),true);

                    String inboundData="<PictureUploadData>"
                            + "<customFaceLibID>iotxiao</customFaceLibID>"
                            + "<FaceAppendData>"
                            + "<name>" + user.getName() + "</name>"
                            + "<customHumanID>" + user.getEmployeeNo() + "</customHumanID>"
                            + "</FaceAppendData>"
                            + "</PictureUploadData>";
                    JSONObject faceBody = JsonHelper.create("FaceDataRecord",
                            inboundData);
                    log.info("inboundData：" + inboundData);
                    try {
                        var faceResponse = httpUtil2.importImage(faceBody, user.getFile());
                        log.info("人脸创建：" + faceResponse.toString());
                    } catch (Exception e) {
                        log.info("人脸创建失败：" + e.getLocalizedMessage());
                        throw new RuntimeException(e);
                    }
                }


            }
        }
        return "创建人员成功";
    }


    /**
     * 添加设备
     *
     * @param deviceSerial 设备序列号
     * @return
     */
    @PostMapping("/basic/devices/create/{deviceSerial}")
    public Object createDevice(@PathVariable String deviceSerial) throws Exception {
        return dService.createDeviceWithserialnumber(deviceSerial);
    }


    /**
     * 添加/修改权限组信息
     *
     * @param request 权限组
     * @return
     * @throws Exception
     */
    @PostMapping("/accessControl/permissionGroups/create")
    public Object putGroup(@Validated @RequestBody GroupInfo request) throws Exception {
        if (StringUtils.isBlank(request.getId())) {
            request.setId(StringUtil.getUUID());
        }
        int result = gService.insert(request);
        if (result > 0) {
            return request.getId();
        }
        throw new Exception("保存失败");
    }


    /**
     * 添加设备到权限组
     *
     * @param deviceIds 需要绑定的设备序列号，数组
     * @param groupId   绑定的权限组ID
     * @return
     * @throws Exception
     */
    @PostMapping("/accessControl/permissionGroups/actions/addDevices/{groupId}")
    public Object GroupAddDevices(@RequestBody List<String> deviceIds, @PathVariable String groupId)
            throws Exception {

        var group = gService.getWithKey(groupId);
        if (group == null || StringUtils.isBlank(group.getId())) {
            throw new Exception("权限组不存在");
        }
        if (deviceIds == null || deviceIds.size() == 0) {
            throw new Exception("请上传需要绑定的设备");
        }
        List<GroupDevice> list = new ArrayList<GroupDevice>();
        List<DeviceInfo> devices = dService.getListWithSerial(deviceIds);
        for (DeviceInfo deviceInfo :
                devices) {
            GroupDevice device = new GroupDevice();
            device.setGroupid(groupId);
            device.setDeviceid(deviceInfo.getDeviceid());
            list.add(device);
        }
        int result = gService.putDevice(list);

        if (result > 0) {
            return "设置成功";
        }
        throw new Exception("设置失败");
    }

    /**
     * 移除设备
     * @param deviceIds 需要移除设备序列号
     * @param groupId 权限组ID
     * @return
     */
    @PostMapping("/accessControl/permissionGroups/actions/removeDevices/{groupId}")
    public Object GroupRemoveDevices(@RequestBody List<String> deviceIds, @PathVariable String groupId) {
        var group = gService.getWithKey(groupId);
        if (group == null || StringUtils.isBlank(group.getId())) {
            throw new RuntimeException("权限组不存在");
        }
        if (deviceIds == null || deviceIds.size() == 0) {
            throw new RuntimeException("请上传需要绑定的设备");
        }

        List<DeviceInfo> devices = dService.getListWithSerial(deviceIds);
        List<String> deviceId = devices.stream().map(a -> a.getDeviceid()).toList();

        int result = gService.removeDeviceFromGroup(groupId,deviceId);

        if (result > 0) {
            //如何批量把这个设备上的这个权限组的所有人员都删了，定时任务处理

            return "移除成功";
        }
        throw new RuntimeException("移除失败");
    }

    /**
     * 从权限组批量移除人员
     * @param employees 用户工号数组
     * @param groupId 权限组ID
     * @return
     */
    @PostMapping("/accessControl/permissionGroups/actions/removeUsers/{groupId}")
    public Object groupRemoveUser(@PathVariable String groupId, @RequestBody List<String> employees) {
        var group = gService.getWithKey(groupId);
        if (group == null || StringUtils.isBlank(group.getId())) {
            throw new RuntimeException("权限组不存在");
        }
        if (employees == null || employees.size() == 0) {
            throw new RuntimeException("请上传需要移除的人员");
        }
        var deviceList = gService.getDeviceInGroup(groupId,"",1, 100);
        if (deviceList.size() == 0) {
            throw new RuntimeException("权限组未绑定设备");
        }

        List<JSONObject> employDels = new ArrayList<>();
        for (String employee :
                employees) {
            employDels.add(JsonHelper.create("employeeNo",employee));
        }
        for (DeviceInfo device:
             deviceList) {
            //删除人员
            HikHttpUtil httpUtil = new HikHttpUtil(device.getIp(), "/ISAPI/AccessControl/UserInfo/Delete",
                    device.getLoginId(), device.getPassword());

            JSONObject body = JsonHelper.create(
                    "UserInfoDelCond",JsonHelper.create("EmployeeList",employDels)
            );

            try {
                var response = httpUtil.doBodyPut(body);
               log.info("移除人员结果：" + response);
            } catch (Exception e) {
                log.info("移除人员失败：" + e.getLocalizedMessage());
                throw new RuntimeException(e);
            }
        }
       return  "移除成功";
    }

    /**
     * 设置门禁周计划
     *
     * @return
     */
    @PostMapping("/access/plans/weeks")
    public String putWeeksPlan(@RequestBody HikWeekPlanRequest request) {

        if (request.getDevices().size() == 0) {
            throw new RuntimeException("请选择需要绑定的设备");
        }
        if (request.getPlans().size() == 0) {
            throw new RuntimeException("请配置具体的周计划");
        }

        log.info("request:" + request.toString());


        JSONObject body = JsonHelper.create("UserRightWeekPlanCfg",
                JsonHelper.create("enable", true, "WeekPlanCfg", request.getPlans()));
        List<DeviceInfo> devices = dService.getListWithSerial(request.getDevices());
        if (devices.size() == 0) {
            throw new RuntimeException("设备错误");
        }

        for (DeviceInfo device :
                devices) {
            //1、配置周计划
            HikHttpUtil httpUtil = new HikHttpUtil(device.getIp(), "/ISAPI/AccessControl/UserRightWeekPlanCfg/" + request.getPlanId(),
                    device.getLoginId(), device.getPassword());
            try {
                var response = httpUtil.doBodyPut(body);
                log.info("周计划配置：" + response.toString() + ",body:" + body.toString());
            } catch (Exception e) {
                log.error("周计划配置失败：" + e.getLocalizedMessage());
                throw new RuntimeException(e);
            }
            //2、配置计划权限

            HikHttpUtil httpUtil2 = new HikHttpUtil(device.getIp(), "/ISAPI/AccessControl/UserRightPlanTemplate/" + request.getPlanId(),
                    device.getLoginId(), device.getPassword());
            JSONObject body2 = JsonHelper.create(
                    "UserRightPlanTemplate",
                    JsonHelper.create("enable",true,
                            "templateName","周计划" + request.getPlanId(),
                            "weekPlanNo",request.getPlanId(),
                            "holidayGroupNo","")
            );
            try {
                var response = httpUtil2.doBodyPut(body2);
                log.info("计划模版配置：" + response.toString() + ",body:" + body.toString());
            } catch (Exception e) {
                log.error("计划模版配置失败：" + e.getLocalizedMessage());
                throw new RuntimeException(e);
            }
        }

        return "计划配置成功";
    }


}
